package com.it.ems.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.it.ems.entity.ExpressOrder;
import com.it.ems.service.ExpressOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.UUID;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.HashMap;
import java.util.Map;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import com.it.ems.entity.User;
import com.it.ems.service.UserService;
import org.springframework.security.access.AccessDeniedException;

@Controller
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private ExpressOrderService expressOrderService;
    @Autowired
    private UserService userService;

    // 定义状态映射：英文 -> 中文，用于前端显示
    private static final Map<String, String> DISPLAY_STATUS_MAP = new HashMap<>();
    static {
        // 兼容英文状态码
        DISPLAY_STATUS_MAP.put("PENDING", "待处理");
        DISPLAY_STATUS_MAP.put("SHIPPED", "已发货");
        DISPLAY_STATUS_MAP.put("PICKED_UP", "已揽收");
        DISPLAY_STATUS_MAP.put("IN_TRANSIT", "运输中");
        DISPLAY_STATUS_MAP.put("UNRECEIVED", "未签收");
        DISPLAY_STATUS_MAP.put("DELIVERED", "已签收");
        DISPLAY_STATUS_MAP.put("CANCELED", "已取消");
        
        // 兼容中文状态（数据库中已存在的数据）
        DISPLAY_STATUS_MAP.put("待处理", "待处理");
        DISPLAY_STATUS_MAP.put("已发货", "已发货");
        DISPLAY_STATUS_MAP.put("已揽收", "已揽收");
        DISPLAY_STATUS_MAP.put("运输中", "运输中");
        DISPLAY_STATUS_MAP.put("未签收", "未签收");
        DISPLAY_STATUS_MAP.put("已签收", "已签收");
        DISPLAY_STATUS_MAP.put("已取消", "已取消");
    }

    @GetMapping("/received")
    public String listReceivedOrders(Model model) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String currentUsername = authentication.getName();
        User currentUser = userService.findByUsername(currentUsername);

        if (currentUser == null) {
            model.addAttribute("error", "无法获取当前用户信息，请重新登录。");
            return "error"; // 或者跳转到登录页
        }

        List<ExpressOrder> receivedOrders = expressOrderService.findReceivedOrdersByUserId(currentUser.getId());
        model.addAttribute("orders", receivedOrders);
        model.addAttribute("displayStatusMap", DISPLAY_STATUS_MAP);
        return "my_received_parcels";
    }

    @GetMapping("/sent")
    public String listSentOrders(Model model) {
        System.out.println("OrderController.listSentOrders method called.");
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String currentUsername = authentication.getName();
        User currentUser = userService.findByUsername(currentUsername);

        if (currentUser == null) {
            model.addAttribute("error", "无法获取当前用户信息，请重新登录。");
            return "error"; // 或者跳转到登录页
        }

        List<ExpressOrder> sentOrders = expressOrderService.findSentOrdersByUserId(currentUser.getId());
        System.out.println("Retrieved sent orders: " + sentOrders.size() + " items.");
        for (ExpressOrder order : sentOrders) {
            System.out.println("Sent Order: ID=" + order.getId() + ", OrderNumber=" + order.getOrderNumber() +
                               ", Sender=" + order.getSenderName() + ", Receiver=" + order.getReceiverName() +
                               ", Status=" + order.getStatus() + ", CreatedAt=" + order.getCreatedAt() +
                               ", Weight=" + order.getWeight() + ", Volume=" + order.getVolume() + ", Price=" + order.getPrice());
        }

        model.addAttribute("orders", sentOrders);
        model.addAttribute("displayStatusMap", DISPLAY_STATUS_MAP);
        return "my_sent_parcels";
    }

    @GetMapping("/send")
    public String showSendParcelForm(Model model) {
        model.addAttribute("expressOrder", new ExpressOrder());
        // 获取当前用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String currentUsername = authentication.getName();
        User currentUser = userService.findByUsername(currentUsername);
        
        if (currentUser == null) {
            model.addAttribute("error", "无法获取当前用户信息，请重新登录。");
            return "error";
        }
        
        // 获取所有普通用户（ROLE_USER），排除当前用户
        List<User> users = userService.findByRole("ROLE_USER", currentUser.getId());
        model.addAttribute("users", users);
        return "send_parcel";
    }

    @PostMapping("/send")
    public String sendParcel(ExpressOrder expressOrder, Model model) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String currentUsername = authentication.getName();
        User currentUser = userService.findByUsername(currentUsername);

        if (currentUser == null) {
            model.addAttribute("error", "寄件失败，无法获取当前用户信息。");
            return "send_parcel";
        }
        expressOrder.setUserId(currentUser.getId());

        // 优先使用用户在下拉框中选择的 receiverId
        if (expressOrder.getReceiverId() == null) {
            // 如果用户没有在下拉框中选择，则根据收件人手机号查找
            User receiverUser = userService.findByPhone(expressOrder.getReceiverPhone());
            if (receiverUser != null) {
                expressOrder.setReceiverId(receiverUser.getId());
            }
            // 如果手机号也没有对应的注册用户，receiverId 保持为 null
        }

        expressOrder.setOrderNumber(UUID.randomUUID().toString().replace("-", "").substring(0, 10).toUpperCase());
        // 设置初始状态
        expressOrder.setStatus("PENDING");
        // 设置创建和更新时间
        expressOrder.setCreatedAt(LocalDateTime.now());
        expressOrder.setUpdatedAt(LocalDateTime.now());

        boolean saved = expressOrderService.save(expressOrder);
        if (saved) {
            model.addAttribute("message", "寄件成功！您的订单号是：" + expressOrder.getOrderNumber());
            return "send_parcel"; // 返回寄件页面并显示成功消息
        } else {
            model.addAttribute("error", "寄件失败，请重试。");
            return "send_parcel"; // 失败后返回寄件页面
        }
    }

    // 检查当前用户是否是管理员
    private void checkAdminRole() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        User currentUser = userService.findByUsername(authentication.getName());
        if (currentUser == null || !currentUser.getRoles().stream().anyMatch(role -> role.getName().equals("ROLE_ADMIN"))) {
            throw new AccessDeniedException("需要管理员权限");
        }
    }

    @GetMapping
    public String listOrders(Model model) {
        checkAdminRole(); // 检查管理员权限
        List<ExpressOrder> orders = expressOrderService.findAllOrders();
        model.addAttribute("orders", orders);
        model.addAttribute("displayStatusMap", DISPLAY_STATUS_MAP);
        return "orders";
    }

    @GetMapping("/{id}")
    @ResponseBody
    public ExpressOrder getOrderById(@PathVariable Long id) {
        checkAdminRole(); // 检查管理员权限
        return expressOrderService.findById(id);
    }

    @GetMapping("/details/{id}")
    @ResponseBody
    public ExpressOrder getOrderDetailsForUser(@PathVariable Long id) {
        System.out.println("getOrderDetailsForUser called with id: " + id);
        
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String currentUsername = authentication.getName();
        System.out.println("Current user: " + currentUsername);
        
        User currentUser = userService.findByUsername(currentUsername);

        if (currentUser == null) {
            System.out.println("Current user is null");
            throw new RuntimeException("无法获取当前用户信息");
        }
        
        System.out.println("Current user ID: " + currentUser.getId());

        ExpressOrder order = expressOrderService.findById(id);
        if (order == null) {
            System.out.println("Order not found for id: " + id);
            throw new RuntimeException("订单不存在");
        }
        
        System.out.println("Order found - userId: " + order.getUserId() + ", receiverId: " + order.getReceiverId());

        // 检查用户是否有权查看此订单（寄件人或收件人）
        if (!order.getUserId().equals(currentUser.getId()) && 
            (order.getReceiverId() == null || !order.getReceiverId().equals(currentUser.getId()))) {
            System.out.println("User has no permission to view this order");
            throw new RuntimeException("无权查看此订单");
        }

        System.out.println("Permission check passed, returning order");
        return order;
    }

    @PostMapping("/update")
    @ResponseBody
    public boolean updateOrder(@RequestBody ExpressOrder expressOrder) {
        checkAdminRole(); // 检查管理员权限
        ExpressOrder existingOrder = expressOrderService.findById(expressOrder.getId());
        if (existingOrder == null) {
            return false; // 订单不存在
        }

        // 只更新允许修改的字段
        existingOrder.setPackageType(expressOrder.getPackageType());
        existingOrder.setWeight(expressOrder.getWeight());
        existingOrder.setVolume(expressOrder.getVolume());
        existingOrder.setPrice(expressOrder.getPrice());
        existingOrder.setStatus(expressOrder.getStatus());
        existingOrder.setUpdatedAt(LocalDateTime.now());

        return expressOrderService.update(existingOrder);
    }

    @PostMapping("/admin/cancel/{id}")
    @ResponseBody
    public boolean cancelOrderByAdmin(@PathVariable Long id) {
        checkAdminRole(); // 检查管理员权限
        ExpressOrder order = expressOrderService.findById(id);
        if (order != null) {
            order.setStatus("CANCELED");
            order.setUpdatedAt(LocalDateTime.now());
            return expressOrderService.update(order);
        }
        return false;
    }

    @PostMapping("/delete/{id}")
    @ResponseBody
    public boolean deleteOrder(@PathVariable Long id) {
        checkAdminRole(); // 检查管理员权限
        return expressOrderService.delete(id);
    }

    @PostMapping("/sign-for/{id}")
    @ResponseBody
    public Map<String, Object> signForParcel(@PathVariable Long id) {
        Map<String, Object> response = new HashMap<>();
        
        // 获取当前用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String currentUsername = authentication.getName();
        User currentUser = userService.findByUsername(currentUsername);
        
        if (currentUser == null) {
            response.put("success", false);
            response.put("message", "无法获取当前用户信息。");
            return response;
        }
        
        ExpressOrder order = expressOrderService.findById(id);
        if (order != null) {
            // 检查用户是否有权签收此订单（必须是收件人）
            if (order.getReceiverId() == null || !order.getReceiverId().equals(currentUser.getId())) {
                response.put("success", false);
                response.put("message", "您无权签收此包裹。");
                return response;
            }
            
            // 检查订单状态是否允许签收（已揽收、已发货、运输中、未签收）
            if (order.getStatus().equals("PICKED_UP") || order.getStatus().equals("SHIPPED") || order.getStatus().equals("IN_TRANSIT") || order.getStatus().equals("UNRECEIVED")) {
                order.setStatus("DELIVERED"); // 更新为英文状态
                order.setUpdatedAt(LocalDateTime.now());
                boolean success = expressOrderService.update(order);
                if (success) {
                    response.put("success", true);
                    response.put("message", "包裹签收成功！");
                } else {
                    response.put("success", false);
                    response.put("message", "签收失败，请重试。");
                }
            } else {
                response.put("success", false);
                response.put("message", "当前订单状态不允许签收。");
            }
        } else {
            response.put("success", false);
            response.put("message", "订单未找到。");
        }
        return response;
    }

    @PostMapping("/cancel/{id}")
    @ResponseBody
    public Map<String, Object> cancelOrderByUser(@PathVariable Long id) {
        Map<String, Object> response = new HashMap<>();
        
        // 获取当前用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String currentUsername = authentication.getName();
        User currentUser = userService.findByUsername(currentUsername);
        
        if (currentUser == null) {
            response.put("success", false);
            response.put("message", "无法获取当前用户信息");
            return response;
        }
        
        ExpressOrder order = expressOrderService.findById(id);
        if (order == null) {
            response.put("success", false);
            response.put("message", "订单不存在");
            return response;
        }
        
        // 检查用户是否有权取消此订单（寄件人或收件人）
        if (!order.getUserId().equals(currentUser.getId()) && 
            (order.getReceiverId() == null || !order.getReceiverId().equals(currentUser.getId()))) {
            response.put("success", false);
            response.put("message", "无权取消此订单");
            return response;
        }
        
        // 只有待处理状态的订单才能取消
        if (!"PENDING".equals(order.getStatus())) {
            response.put("success", false);
            response.put("message", "只有待处理状态的订单才能取消");
            return response;
        }
        
        // 取消订单
        order.setStatus("CANCELED");
        order.setUpdatedAt(LocalDateTime.now());
        boolean success = expressOrderService.update(order);
        
        if (success) {
            response.put("success", true);
            response.put("message", "订单取消成功");
        } else {
            response.put("success", false);
            response.put("message", "取消订单失败，请重试");
        }
        
        return response;
    }

    @GetMapping("/track/{orderNumber}")
    @ResponseBody
    public List<ExpressOrder> getOrderByOrderNumber(@PathVariable String orderNumber) {
        return expressOrderService.findByOrderNumber(orderNumber);
    }
} 